package nl.hro.mobiqueen.data;

import java.util.Vector;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.content.Context;
import android.util.Base64;

public class DatabaseSynchronizer {
	public static final String NAMESPACE = "http://mobiqueen.waltertamboer.nl/";
	public static final String URL = "http://mobiqueen.waltertamboer.nl/";
	public static final String METHOD_GET_ARTISTS = "getArtists";
	public static final String METHOD_GET_EVENTS = "getEvents";
	public static final String METHOD_GET_PODIA = "getPodia";

	private DatabaseAdapter db;

	public DatabaseSynchronizer(Context context) {
		db = new DatabaseAdapter(context);
		db.open();
	}

	public void syncArtists() {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_GET_ARTISTS);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE aht = new HttpTransportSE(URL);

		try {
			aht.call(NAMESPACE + METHOD_GET_ARTISTS, envelope);
			@SuppressWarnings("unchecked")
			Vector<SoapObject> response = (Vector<SoapObject>) envelope
					.getResponse();

			// Iterate artists
			for (SoapObject items : response) {
				// Initialize artist properties
				Integer id = null;
				String name = null;
				String description = null;
				// Fill artist properties
				for (int i = 0; i < items.getPropertyCount(); i++) {
					SoapObject item = (SoapObject) items.getProperty(i);
					String key = (String) item.getProperty("key");
					Object value = item.getProperty("value");
					if (key.equals("id")) {
						id = Integer.parseInt(value.toString());
					} else if (key.equals("name")) {
						name = value.toString();
					} else if (key.equals("description")) {
						description = value.toString();
					}
				}
				// Insert or update artist
				if (db.findArtist(id).getCount() == 0) {
					db.insertArtist(id, name, description);
				} else {
					db.updateArtist(id, name, description);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			// TODO handle errors properly
		}
	}

	public void syncEvents() {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_GET_EVENTS);
		PropertyInfo begHour = new PropertyInfo();
		begHour.setName("begHour");
		begHour.setValue(0);
		begHour.setType(int.class);
		request.addProperty(begHour);
		PropertyInfo endHour = new PropertyInfo();
		endHour.setName("endHour");
		endHour.setValue(24);
		endHour.setType(int.class);
		request.addProperty(endHour);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE aht = new HttpTransportSE(URL);

		try {
			aht.call(NAMESPACE + METHOD_GET_EVENTS, envelope);
			@SuppressWarnings("unchecked")
			Vector<SoapObject> response = (Vector<SoapObject>) envelope
					.getResponse();

			// Iterate artists
			for (SoapObject items : response) {
				// Initialize event properties
				Integer id = null;
				Integer podium = null;
				Integer artist = null;
				String startTime = null;
				String endTime = null;
				String genre = null;

				// Fill event properties
				for (int i = 0; i < items.getPropertyCount(); i++) {
					SoapObject item = (SoapObject) items.getProperty(i);
					String key = (String) item.getProperty("key");
					Object value = item.getProperty("value");
					if (key.equals("id")) {
						id = Integer.parseInt(value.toString());
					} else if (key.equals("podium")) {
						podium = Integer.parseInt(value.toString());
					} else if (key.equals("artist")) {
						artist = Integer.parseInt(value.toString());
					} else if (key.equals("start_time")) {
						startTime = value.toString();
					} else if (key.equals("end_time")) {
						endTime = value.toString();
					} else if (key.equals("genre")) {
						genre = value.toString();
					}
				}
				// Insert or update event
				if (db.findEvent(id).getCount() == 0) {
					db.insertEvent(id, podium, artist, startTime, endTime,
							genre);
				} else {
					db.updateEvent(id, podium, artist, startTime, endTime,
							genre);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			// TODO handle errors properly
		}
	}

	public void syncPodia() {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_GET_PODIA);
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
				SoapEnvelope.VER11);
		envelope.setOutputSoapObject(request);
		HttpTransportSE aht = new HttpTransportSE(URL);

		try {
			aht.call(NAMESPACE + METHOD_GET_PODIA, envelope);
			@SuppressWarnings("unchecked")
			Vector<SoapObject> response = (Vector<SoapObject>) envelope
					.getResponse();

			// Iterate artists
			for (SoapObject items : response) {
				// Initialize podium properties
				Integer id = null;
				String name = null;
				String description = null;
				Double longitude = null;
				Double latitude = null;
				byte[] mapsIcon = null;

				// Fill podium properties
				for (int i = 0; i < items.getPropertyCount(); i++) {
					SoapObject item = (SoapObject) items.getProperty(i);
					String key = (String) item.getProperty("key");
					Object value = item.getProperty("value");
					if (key.equals("id")) {
						id = Integer.parseInt(value.toString());
					} else if (key.equals("name")) {
						name = value.toString();
					} else if (key.equals("description")) {
						description = value.toString();
					} else if (key.equals("longitude")) {
						longitude = Double.parseDouble(value.toString());
					} else if (key.equals("latitude")) {
						latitude = Double.parseDouble(value.toString());
					} else if (key.equals("icon_maps")) {
						mapsIcon = Base64.decode(value.toString(),
								Base64.DEFAULT);
					}
				}
				// Insert or update podium
				if (db.findPodium(id).getCount() == 0) {
					db.insertPodium(id, name, description, latitude, longitude, mapsIcon);
				} else {
					db.updatePodium(id, name, description, latitude, longitude, mapsIcon);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			// TODO handle errors properly
		}
	}
}